﻿using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using HDM.NexusEngine.Input;

namespace HDM.NexusEngine.Core
{
    public class VerticalMenu
    {
        private Vector _postion = new Vector();
        private InputManager _input;
        private List<Button> _buttons = new List<Button>();
        private bool _inDown;
        private bool _inUp;
        private int _currentFocus;

        public double Spacing { get; set; }

        public VerticalMenu(double x, double y, InputManager input)
        {
            _input = input;
            _postion = new Vector(x, y, 0);
            Spacing = 50;
        }

        public void AddButton(Button button)
        {
            var currentY = _postion.Y;

            if (_buttons.Count != 0)
            {
                currentY = _buttons.Last().Position.Y;
                currentY -= Spacing;
            }
            else
            {
                // It's the first button added, it should have focus.
                button.OnGainFocus();
            }

            button.Position = new Vector(_postion.X, currentY, 0);
            _buttons.Add(button);
        }

        public void Render(Renderer renderer)
        {
            _buttons.ForEach(x => x.Render(renderer));
        }

        public void HandleInput()
        {
            var controlPadDown = false;
            var controlPadUp = false;

            if (_input.Controller != null)
            {
                var invertY = _input.Controller.LeftControlStick.Y * -1;

                if (invertY < -0.2)
                {
                    // The control stick is pulled down.
                    if (_inDown == false)
                    {
                        controlPadDown = true;
                        _inDown = true;
                    }
                }
                else
                {
                    _inDown = false;
                }

                if (invertY > 0.2)
                {
                    if (_inUp == false)
                    {
                        controlPadUp = true;
                        _inUp = true;
                    }
                }
                else
                {
                    _inUp = false;
                }
            }
            
            if (_input.Keyboard.IsKeyPressed(Keys.Down) || controlPadDown)
            {
                OnDown();
            }
            else if (_input.Keyboard.IsKeyPressed(Keys.Up) || controlPadUp)
            {
                OnUp();
            }
            else if (_input.Keyboard.IsKeyPressed(Keys.Enter) || (_input.Controller != null && _input.Controller.ButtonA.Pressed))
            {
                OnButtonPress();
            }
        }

        private void OnUp()
        {
            var oldFocus = _currentFocus;
            _currentFocus++;
            if (_currentFocus == _buttons.Count)
            {
                _currentFocus = 0;
            }
            ChangeFocus(oldFocus, _currentFocus);
        }

        private void OnDown()
        {
            var oldFocus = _currentFocus;
            _currentFocus--;
            if (_currentFocus == -1)
            {
                _currentFocus = (_buttons.Count - 1);
            }
            ChangeFocus(oldFocus, _currentFocus);
        }

        private void OnButtonPress()
        {
            _buttons[_currentFocus].OnPress();
        }

        private void ChangeFocus(int from, int to)
        {
            if (from != to)
            {
                _buttons[from].OnLosrFocus();
                _buttons[to].OnGainFocus();
            }
        }
    }
}